﻿Imports System.IO
Imports System.Threading
Imports System.ComponentModel

Public Class Form1
    Dim extentionarray As New ArrayList
    Dim fileCount As Integer = 0
    Dim mainDir As String

    'Private WithEvents backgroundWorker1 As System.ComponentModel.BackgroundWorker

    Private Sub btnGo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGo.MouseUp
        'disable all the buttons
        For Each ctl As Control In Controls
            ctl.Enabled = False
        Next

        'set the filename to something blank if no copying
        If rdbFileNone.Checked = True Then
            txtFileDestination.Text = "*"
        End If
        lstErrors.Items.Clear()

        If rdbFileAllRoot.Checked = True Or rdbFileArtistAndTitle.Checked = True Or rdbFileArtistTitle.Checked = True Then
            If Directory.Exists(txtFileDestination.Text) = False Then
                Try
                    Directory.CreateDirectory(txtFileDestination.Text)
                Catch ex As Exception
                    MessageBox.Show("Couldn't create route directory")
                    lstErrors.Items.Add(ex.ToString)
                End Try
            Else
                If MsgBox("Target Directory Exists, Copy Anyway?", MsgBoxStyle.YesNo) = MsgBoxResult.No Then
                    rdbFileNone.Checked = True
                    rdbFileArtistTitle.Checked = False
                    rdbFileArtistAndTitle.Checked = False
                    rdbFileAllRoot.Checked = False
                End If
            End If
        End If

        ProgressBar1.Value = 0
        fileCount = 0


        For Each Item In lstExt.Items
            extentionarray.Add(Item)
        Next
        If txtMainDir.Text = "" Then
            MessageBox.Show("Please set directory")
        Else
            'try setting the maindir count
            Try
                ProgressBar1.Maximum = Directory.EnumerateDirectories(txtMainDir.Text).Count
            Catch ex As Exception
                'do nothing
            End Try

            If BackgroundWorker1.IsBusy <> True Then
                'Start the asynchronous operation.
                mainDir = txtMainDir.Text
                BackgroundWorker1.RunWorkerAsync()
            Else
                MsgBox("Could not start Process!", MsgBoxStyle.OkOnly, "Error starting!")
            End If
        End If

    End Sub

    'threadded stuff
    Public Sub New()
        InitializeComponent()
    End Sub

    Private Sub backgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As DoWorkEventArgs) Handles backgroundWorker1.DoWork
        Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)

        If Directory.Exists(mainDir) Then
            For Each subdir As String In Directory.GetDirectories(mainDir)
                If (subdir IsNot Nothing) And (subdir.Contains(txtFileDestination.Text) = False) Then
                    searchForVideo(subdir)
                    If chkRecursive.Checked = True Then
                        searchSubDirectorys(subdir)
                    End If
                End If
                worker.ReportProgress(1)
            Next
            searchForVideo(mainDir)
            worker.ReportProgress(1)
        End If

    End Sub

    Private Sub backgroundWorker1_ProgressChanged(ByVal sender As System.Object, ByVal e As ProgressChangedEventArgs) Handles backgroundWorker1.ProgressChanged
        ProgressBar1.Increment(e.ProgressPercentage)
    End Sub

    Private Sub backgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) Handles backgroundWorker1.RunWorkerCompleted
        Me.Focus()

        'enable all the buttons
        For Each ctl As Control In Controls
            ctl.Enabled = True
        Next
        'check the enabled thing on the groupbox
        If rdbFileNone.Checked = True Then
            grpFileCopyOpts.Enabled = False
        Else
            grpFileCopyOpts.Enabled = True
        End If

        lblCreated.Text = fileCount.ToString

        If fileCount = 0 Then
            MessageBox.Show("No files created, check directory and settings")
        Else
            MessageBox.Show("Done!")
        End If

    End Sub


    Private Sub searchSubDirectorys(ByVal mainDir As String)
        If Directory.Exists(mainDir) Then
            For Each subdir As String In Directory.GetDirectories(mainDir)
                If (subdir IsNot Nothing) And (subdir.Contains(txtFileDestination.Text) = False) Then
                    searchForVideo(subdir)
                    If chkRecursive.Checked = True Then
                        searchSubDirectorys(subdir)
                    End If
                End If
            Next
        End If
    End Sub

    Private Sub searchForVideo(ByVal dir As String)
        Dim musicTitle As String = ""
        Dim musicArtist As String = ""
        Dim filename As String
        Dim fileext As String
        Dim dashCheck As String


        For Each filepath As String In Directory.GetFiles(dir)
            Try
                fileext = filepath.Substring(filepath.LastIndexOf(".") + 1)
                If extentionarray.Contains(fileext) Then
                    filename = filepath

                    If chkUnderscore.Checked = True Then
                        filename = filename.Replace("_", " ")
                    End If

                    filename = filename.Substring(filename.LastIndexOf("\") + 1)

                    If chkDots.Checked = True Then
                        If (Len(filename.Substring(0, filename.LastIndexOf("."))) - Len((filename.Substring(0, filename.LastIndexOf("."))).Replace(".", ""))) >= CInt(txtDots.Text) Then
                            filename = filename.Substring(0, filename.LastIndexOf(".")).Replace(".", " ") + filename.Substring(filename.LastIndexOf("."))
                        End If
                    End If

                    If filename.Contains("-") = True Then
                        If chkTrackNo.Checked = True Then
                            If IsNumeric(filename.Substring(0, (filename.Replace(" ", "")).IndexOf("-"))) = True Then
                                filename = filename.Substring(filename.IndexOf("-") + 1)
                            End If

                            If chkTrackNoExtra.Checked = True Then
                                If IsNumeric((filename.Replace(" ", "")).Substring(0, 3)) = True Then
                                    filename = filename.Substring(3)
                                End If
                            End If
                            If filename.Substring(0, 1) = "." Then
                                filename = filename.Substring(1)
                            End If
                            If filename.Substring(0, 1) = " " Then
                                filename = filename.Substring(1)
                            End If
                        End If

                        If chkHyphen.Checked = True Then
                            If chkFallbackArtist.Checked = True Then
                                If filename.Contains(" - ") Then
                                    dashCheck = " - "
                                Else
                                    dashCheck = "-"
                                End If
                            Else
                                dashCheck = " - "
                            End If
                        Else
                            dashCheck = "-"
                        End If

                        musicArtist = filename.Substring(0, filename.IndexOf(dashCheck))

                        If musicArtist.Substring(musicArtist.Length - 1) = " " Then
                            musicArtist = musicArtist.Substring(0, musicArtist.Length - 1)
                        End If
                        If musicArtist.Substring(0, 1) = " " Then
                            musicArtist = musicArtist.Substring(1)
                        End If

                        musicTitle = filename.Substring(filename.IndexOf(dashCheck) + 1)

                        musicTitle = musicTitle.Substring(0, musicTitle.LastIndexOf("."))
                        If dashCheck = " - " Then
                            musicTitle = musicTitle.Substring(1)
                        End If
                        If musicTitle.Substring(0, 1) = " " Then
                            musicTitle = musicTitle.Substring(1)
                        End If
                        If musicTitle.Contains("-") Then
                            musicTitle = musicTitle.Substring(0, musicTitle.IndexOf("-"))
                        End If
                        If musicTitle.Substring(musicTitle.Length - 1) = " " Then
                            musicTitle = musicTitle.Substring(0, musicTitle.Length - 1)
                        End If
                        If chkCaseArtists.Checked = True Then
                            musicArtist = Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(musicArtist)
                        End If
                        If chkCaseTitles.Checked = True Then
                            musicTitle = Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(musicTitle)
                        End If
                    Else
                        If chkDashless.Checked = True Then
                            musicTitle = filename.Substring(0, filename.LastIndexOf("."))
                            musicArtist = "Unknown"
                            lstErrors.Items.Add("Added " + musicArtist + " - " + musicTitle + " As couldn't find An Artist")
                        End If
                    End If


                    createNFO(filepath, musicTitle, musicArtist)
                Else
                    If lstErrors.Items.Contains("Ignored Filetype " + fileext) = False Then
                        If chkFileTypes.Checked = True Then
                            lstErrors.Items.Add("Ignored Filetype " + fileext)
                        End If
                    End If
                End If

            Catch ex As Exception
                lstErrors.Items.Add(filepath)
            End Try
        Next
    End Sub

    Private Sub createNFO(ByVal filename As String, ByVal songTitle As String, ByVal songArtist As String)
        Dim fileobj, MyFile
        Dim shouldCreate As Boolean = True

        If rdbFileAllRoot.Checked = True Or rdbFileArtistAndTitle.Checked = True Or rdbFileArtistTitle.Checked = True Then
            filename = copy_new_files(filename, songTitle, songArtist)
        End If

        If File.Exists(filename.Substring(0, filename.LastIndexOf(".")) + ".nfo") Then
            If chkNFOdelete.Checked = True Then
                File.Delete(filename.Substring(0, filename.LastIndexOf(".")) + ".nfo")
            ElseIf chkNFOrename.Checked = True Then
                File.Copy(filename.Substring(0, filename.LastIndexOf(".")) + ".nfo", filename.Substring(0, filename.LastIndexOf(".")) + " - " + Format(Now, "yyyymmddhhmmss") + " backup.nfo", False)
                File.Delete(filename.Substring(0, filename.LastIndexOf(".")) + ".nfo")
            ElseIf chkNFOskip.Checked = True Then
                shouldCreate = False
            End If
        End If

        If shouldCreate = True Then
            If chkDebug.Checked = True Then
                lstErrors.Items.Add(songArtist + " - " + songTitle)
            End If

            fileobj = CreateObject("Scripting.FileSystemObject")
            MyFile = fileobj.CreateTextFile(filename.Substring(0, filename.LastIndexOf(".")) + ".nfo", True)
            MyFile.WriteLine("<musicvideo>")
            MyFile.WriteLine("<title>" + songTitle + "</title>")
            MyFile.WriteLine("<artist>" + songArtist + "</artist>")

            If chkArtistAlbum.Checked = True Then
                MyFile.WriteLine("<album>" + songArtist + "</album>")
            End If

            If chkGenre.Checked = True Then
                MyFile.WriteLine("<genre>" + txtGenre.Text + "</genre>")
            End If

            If CheckBoxDirector.Checked = True Then
                MyFile.WriteLine("<director>" + TextBoxDirector.Text + "</director>")
            End If

            If CheckBoxComposer.Checked = True Then
                MyFile.WriteLine("<composer>" + TextBoxComposer.Text + "</composer>")
            End If

            If CheckBoxStudio.Checked = True Then
                MyFile.WriteLine("<studio>" + TextBoxStudio.Text + "</studio>")
            End If

            If CheckBoxYear.Checked = True Then
                MyFile.WriteLine("<year>" + TextBoxYear.Text + "</year>")
            End If

            If CheckBoxRuntime.Checked = True Then
                MyFile.Writeline("<runtime>" + TextBoxRuntime.Text + "</runtime>")
            End If

            MyFile.WriteLine("</musicvideo>")
            MyFile.Close()

            fileCount = fileCount + 1
        Else
            If chkOutputSkipped.Checked = True Then
                lstErrors.Items.Add("Skipped existing NFO " + songArtist + " - " + songTitle)
            End If
        End If

            'generate thumbnail if option checked
            If chkGetThumbnail.Checked = True Then
                'if overwirte is disabled, generate thumbnail if the file doesn't exist
                If chkThumnailDelete.Checked = False Then
                    If File.Exists(filename.Substring(0, filename.LastIndexOf(".")) + ".tbn") = False Then
                        generate_thumbnail(filename)
                    End If
                Else
                    'if overwrite is ticked, make thumnail anyway!
                    generate_thumbnail(filename)
                End If
            End If

    End Sub

    Private Sub generate_thumbnail(ByVal filename As String)
        'Create image with ffmpeg
        Shell("ffmpeg.exe " + "-y -itsoffset -" + numVideoDur.Value.ToString + "  -i " + Chr(34) + filename + Chr(34) + " -vcodec mjpeg -vframes 1 -an -f rawvideo " + Chr(34) + filename.Substring(0, filename.LastIndexOf(".")) + ".tbn" + Chr(34), AppWinStyle.Hide, True, 60000)

        'Dim myProcess As New Process
        'Dim myProcessStartInfo As New ProcessStartInfo
        'myProcessStartInfo.FileName = "ffmpeg"
        ''myProcessStartInfo.Arguments = "-i " + Chr(34) + filename + Chr(34) + " -f mjpeg -t 0.001 -ss " + numVideoDur.Value.ToString + " -y " + Chr(34) + filename.Substring(0, filename.LastIndexOf(".")) + ".tbn" + Chr(34)
        'myProcessStartInfo.Arguments = "-y -itsoffset -" + numVideoDur.Value.ToString + "  -i " + Chr(34) + filename + Chr(34) + " -vcodec mjpeg -vframes 1 -an -f rawvideo " + Chr(34) + filename.Substring(0, filename.LastIndexOf(".")) + ".tbn" + Chr(34)
        'myProcessStartInfo.WindowStyle = ProcessWindowStyle.Hidden
        'myProcessStartInfo.RedirectStandardOutput = True
        'myProcessStartInfo.UseShellExecute = False
        'myProcess.StartInfo = myProcessStartInfo
        'myProcess.Start()
        'Dim myStreamReader As StreamReader = myProcess.StandardOutput
        '' Read the standard output of the spawned process.
        'Dim myString As String = myStreamReader.ReadToEnd()
        'myProcess.Close()

    End Sub

    Private Function copy_new_files(ByVal filename As String, ByVal songTitle As String, ByVal songArtist As String) As String
        'main folder created at start

        Dim filepath As String = filename
        'dir does not have \ at end
        Dim filedir As String = filename.Substring(0, filename.LastIndexOf("\"))
        'name(doesn) 't include \ or .
        Dim filejustname As String = filename.Substring(filename.LastIndexOf("\") + 1)
        'fileext in this string includes leading dot
        Dim fileextention As String = filename.Substring(filename.LastIndexOf("."))
        filejustname = filejustname.Substring(0, filejustname.LastIndexOf("."))
        'this name doesn't include an extention or dor
        Dim filefinalname As String = ""

        'check for \ that could error
        If txtFileDestination.Text.Substring(txtFileDestination.Text.Length - 1) = "\" Then
            txtFileDestination.Text = txtFileDestination.Text.Substring(1)
        End If

        If rdbFileAllRoot.Checked = True Then
            'all songs in one folder
            filefinalname = txtFileDestination.Text + "\" + filejustname
        End If

        If rdbFileArtistAndTitle.Checked = True Then
            'own artist and song folder
            If Directory.Exists(txtFileDestination.Text + "\" + songArtist) = False Then
                Directory.CreateDirectory(txtFileDestination.Text + "\" + songArtist)
            End If
            Directory.CreateDirectory(txtFileDestination.Text + "\" + songArtist + "\" + songTitle)

            filefinalname = txtFileDestination.Text + "\" + songArtist + "\" + songTitle + "\" + filejustname
        End If

        If rdbFileArtistTitle.Checked = True Then
            Directory.CreateDirectory(txtFileDestination.Text + "\" + songArtist + " " + songTitle)
            filefinalname = txtFileDestination.Text + "\" + songArtist + " " + songTitle + "\" + filejustname
        End If

        'change file name
        If chkRenameAll.Checked = True Then
            filefinalname = filefinalname.Substring(0, filefinalname.LastIndexOf("\") + 1) + songArtist + " - " + songTitle
        End If

        Try
            If rdbMoveFileNfoOnly.Checked = True Then
                If File.Exists(filedir + "\" + filejustname + ".nfo") Then
                    File.Copy(filedir + "\" + filejustname + ".nfo", filefinalname + ".nfo", chkOverWrite.Checked)
                End If
            End If

            If rdbMoveFiletypes.Checked = True Then
                Dim templst As New ArrayList({".jpg", ".png", ".tbn", ".txt", ".xml", ".nfo"})
                For Each tempfile As String In Directory.GetFiles(filedir)
                    If templst.Contains(tempfile.Substring(tempfile.LastIndexOf(".")).ToLower) Then
                        File.Copy(tempfile, filefinalname.Substring(0, filefinalname.LastIndexOf("\")) + tempfile.Substring(tempfile.LastIndexOf("\")), chkOverWrite.Checked)
                    End If
                Next
            End If

            ' moves similarly named files
            If rdbMoveNonVideo.Checked = True Then
                For Each tempfile As String In Directory.GetFiles(filedir)
                    If tempfile.Substring(tempfile.LastIndexOf("\") + 1, (tempfile.LastIndexOf(".") - tempfile.LastIndexOf("\")) - 1) = filejustname Then
                        If extentionarray.Contains(tempfile.Substring(tempfile.LastIndexOf(".") + 1)) = False Then
                            File.Copy(tempfile, filefinalname + tempfile.Substring(tempfile.LastIndexOf(".")), chkOverWrite.Checked)
                        End If
                    End If
                Next
            End If

            If rdbMoveAllFiles.Checked = True Then
                For Each tempfile As String In Directory.GetFiles(filedir)
                    If extentionarray.Contains(tempfile.Substring(tempfile.LastIndexOf(".") + 1)) = False Then
                        File.Copy(tempfile, filefinalname.Substring(0, filefinalname.LastIndexOf("\")) + tempfile.Substring(tempfile.LastIndexOf("\")), chkOverWrite.Checked)
                    End If
                Next
            End If

            'Copy actual video
            File.Copy(filename, filefinalname + fileextention, chkOverWrite.Checked)
        Catch ex As Exception
            lstErrors.Items.Add("Did not overwrite " + filefinalname + fileextention)
        End Try

        filepath = filefinalname + fileextention
        Return filepath
    End Function

    Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click
        If txtAdd.Text <> "" Then
            If txtAdd.Text.Substring(0, 1) = "." Then
                txtAdd.Text = txtAdd.Text.Substring(1)
            End If
            lstExt.Items.Add(txtAdd.Text)
            txtAdd.Text = ""
        End If
    End Sub

    Private Sub btnRemove_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRemove.Click
        lstExt.Items.Remove(lstExt.SelectedItem)
    End Sub

    Private Sub btnBrowse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBrowse.Click
        FolderBrowserDialog1.ShowDialog()
        If FolderBrowserDialog1.SelectedPath IsNot Nothing Then
            txtMainDir.Text = FolderBrowserDialog1.SelectedPath.ToString
            If (txtFileDestination.Text = "") And (txtMainDir.Text <> "") Then
                txtFileDestination.Text = txtMainDir.Text + "\Music Videos " + Format(Now, "yyyy-mm-dd hh-mm-ss")
            End If
        End If
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkRecursive.MouseEnter
        ToolTip1.Show("Tick this if folder structures are deeper than 2 levels", Me, chkRecursive.Bottom, chkRecursive.Right, 2000)
    End Sub

    Private Sub btnFileDestination_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFileDestination.Click
        FolderBrowserDialog1.ShowDialog()
        If FolderBrowserDialog1.SelectedPath IsNot Nothing Then
            txtFileDestination.Text = FolderBrowserDialog1.SelectedPath.ToString
            If txtFileDestination.Text = txtMainDir.Text Then
                MessageBox.Show("Outputting to input directory not recommended!")
            End If
            If Directory.Exists(txtFileDestination.Text) Then
                If MsgBox("Directory Exists, Use Anyway?", MsgBoxStyle.OkCancel) = MsgBoxResult.Cancel Then
                    txtFileDestination.Text = ""
                End If
            End If
        End If
    End Sub

    Private Sub rdbFileNone_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rdbFileNone.CheckedChanged
        If rdbFileNone.Checked = True Then
            grpFileCopyOpts.Enabled = False
        Else
            grpFileCopyOpts.Enabled = True
        End If
    End Sub

    Public FFMPEGisWorking As Boolean = False
    Private Sub CheckBox1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkGetThumbnail.CheckedChanged
        If chkGetThumbnail.Checked = True Then
            Try
                MessageBox.Show("Preliminary check of ffmpeg functionality... Press OK to Start", "Lets make sure ffmpeg is working...")
                Dim myProcess As New Process()
                Dim myProcessStartInfo As New ProcessStartInfo("ffmpeg")
                myProcessStartInfo.Arguments = ""
                myProcessStartInfo.WindowStyle = ProcessWindowStyle.Hidden
                myProcessStartInfo.UseShellExecute = False
                myProcessStartInfo.RedirectStandardOutput = True
                myProcess.StartInfo = myProcessStartInfo
                myProcess.Start()

                Dim myStreamReader As StreamReader = myProcess.StandardOutput
                'Read the standard output of the spawned process.
                Dim myString As String = myStreamReader.ReadToEnd()
                myProcess.Close()
                If myString.Contains("Hyper fast Audio and Video encoder") Then
                    MessageBox.Show("Congratulations! FFMpeg is running as smooth as a greesed up pig!" + vbNewLine + "FFMpeg can take 3-10 seconds per video if your pc blows chunks", "Hohhh Yeah We Greesy!")
                Else
                    MsgBox("FFmpeg Appears to not be working or the wrong version ERROR:FF1")
                    chkGetThumbnail.Checked = False
                End If
            Catch ex As Exception
                MsgBox("FFmpeg Could not be found or is not working ERROR:FF2")
                chkGetThumbnail.Checked = False
            End Try
        End If
    End Sub

    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
        If Me.Enabled = False Then
            If MsgBox("Really Exit and Stop Whatever is happening?", MsgBoxStyle.YesNo, "Really Exit?") = MsgBoxResult.No Then
                e.Cancel = True
            Else
                If backgroundWorker1.WorkerSupportsCancellation = True Then
                    'Cancel the asynchronous operation.
                    backgroundWorker1.CancelAsync()
                Else
                    MsgBox("Could not cancel", vbOKOnly, "Error")
                End If
            End If
        End If
    End Sub

    Private Sub chkRenameAll_CheckChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkRenameAll.CheckedChanged
        If chkRenameAll.Checked = True Then
            MessageBox.Show("Recommended use:" + vbNewLine + "'Artist Title Folders' " + vbNewLine + "'All Similarly Named Files'")
        End If
    End Sub

    Private Sub txtGenre_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtGenre.TextChanged

    End Sub

    Private Sub chkGenre_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkGenre.CheckedChanged

    End Sub

    Private Sub CheckBox1_CheckedChanged_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBoxDirector.CheckedChanged

    End Sub

    Private Sub BackgroundWorker1_DoWork_1(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork

    End Sub

    Private Sub Form1_Load_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    End Sub

    Private Sub Label9_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)

    End Sub

    Private Sub lstExt_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstExt.SelectedIndexChanged

    End Sub

    Private Sub Form1_Load_2(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    End Sub
End Class
